#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


#define DEFAULT_PORT	5019
struct sockaddr_in local, client_addr;
HANDLE t,Accept1,a[5];
int mutex=1;
FILE *des;
void wait(int *mutex);
void signal(int *mutex);
void Send(SOCKET *sockClient);
void Rec(SOCKET sockClient);
int addr_len;
SOCKET msg_sock[10] = {0};
int qb = 0;
int number;
void wait(int *mutex)
{
	while (*mutex <= 0);
	*mutex--;
}

void signal(int *mutex)
{
	*mutex++;
}

void Rec(SOCKET sockClient)
{
	char szBUFF[1000];
	int SEND;
	int b;
	char a[20];
	int Receive;
	int num;
	while (1)
	{
		//WaitForSingleObject(hMutex, INFINITE);
		Receive = recv(sockClient, szBUFF, sizeof(szBUFF), 0);
		if (Receive <= 0)		
		{
			break;
		}
		a[0] = szBUFF[0];
		b = atoi(a);
		if (b==0 && strcmp(szBUFF,"Bye")!=0){
			for (int j = 0; j < number; j++){
				SEND = send(msg_sock[j], szBUFF, sizeof(szBUFF), 0);
			}
			printf("%s\n", szBUFF);
		}
		else{
			/*printf("char :%c\n", a);
			b = atoi(a);
			printf("int :%d\n", b);*/
			SEND = send(msg_sock[b], szBUFF, sizeof(szBUFF), 0);
			//SEND = send(msg_sock[0], szBUFF, sizeof(szBUFF), 0);
			//SEND = send(msg_sock[1], szBUFF, sizeof(szBUFF), 0);
			printf("%s\n", szBUFF);
		}
		wait(&mutex);
		des = fopen("server.txt", "a+");
		fprintf(des, "Receive: %s\n",szBUFF);
		fclose(des);
		signal(&mutex);
		Sleep(1000);
		//Sleep(1000);
		//ReleaseMutex(hMutex);
	}
	closesocket(sockClient);  
}

void Acc(SOCKET sock)
{
	addr_len = sizeof(client_addr);
	int SEND;
	number = 1;
	char str[25];
	while (addr_len>0&&number<10)
	{
		msg_sock[number] = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
		printf("connect successfully:%d\n",number);
		SEND = send(msg_sock[number], _itoa(number, str,10), 25, 0);
		if (number == 10)
		{
			break;
		}
		a[number] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Rec, (LPVOID)msg_sock[number], 0, 0);
		t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Send, (LPVOID)&msg_sock,  0, 0);		
		number++;
	}
	WaitForSingleObject(a, INFINITE);
	WaitForSingleObject(t, INFINITE);
	CloseHandle(a);
	CloseHandle(t);
}

void Send(SOCKET *sockClient)
{
	char message[1000];
	int SEND;
	while (1)
	{
		//WaitForSingleObject(hMutex, INFINITE);
		gets_s(message, 100);
		for (int i = 1; i <= sizeof(sockClient); i++)
		{
			SEND = send(sockClient[i], message, sizeof(message), 0);
			wait(&mutex);
			des = fopen("server.txt", "a+");
			fprintf(des, "Send: %s\n", message);
			fclose(des);
			signal(&mutex);
			if (SEND <= 0)
			{
				break;
			}
			else if (SEND > 0 && strcmp(message, "Bye") == 0)
			{
				break;
			}
			Sleep(1000);
		}
	}	
	closesocket(*sockClient);
	//WSACleanup();
}



int main(int argc, char **argv) 
{
	
	SOCKET sock;
	WSADATA wsaData;

	if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR) {
		// stderr: standard error are printed to the screen.
		fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError());
		//WSACleanup function terminates use of the Windows Sockets DLL. 
		WSACleanup();
		return -1;
	}
	// Fill in the address structure
	local.sin_family = AF_INET;
	local.sin_addr.s_addr = INADDR_ANY;
	local.sin_port = htons(DEFAULT_PORT);
	//sock[0] = socket(AF_INET, SOCK_STREAM, 0);	//TCp socket


		/*local.sin_family = AF_INET;
		local.sin_addr.s_addr = INADDR_ANY;
		local.sin_port = htons(DEFAULT_PORT);*/
		sock = socket(AF_INET, SOCK_STREAM, 0);	//TCp socket
		

		if (sock == INVALID_SOCKET) {
			fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError());
			WSACleanup();
			return -1;
		}
		
		if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR) {
			fprintf(stderr, "bind() failed with error %d\n", WSAGetLastError());
			WSACleanup();
			return -1;
		}

		printf("Listening\n");
	if (listen(sock, 100) == SOCKET_ERROR) {
		fprintf(stderr, "listen() failed with error %d\n", WSAGetLastError());
		WSACleanup();
	}
	if (listen(sock, 100) != SOCKET_ERROR)
	{
		Accept1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Acc, (LPVOID)sock, 0, 0);
		WaitForSingleObject(Accept1, INFINITE);
	}
		//waiting for the connections
		printf("Waiting for the connections ........\n");
		///while (1)
		//{
		//addr_len = sizeof(client_addr);
		//msg_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
		//addr_len = sizeof(client_addr);
		//msg_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
		printf("accepted connection from %s, port %d\n", inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port));		
		CloseHandle(Accept1);
		//closesocket(msg_sock);
		WSACleanup();
}